﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Windows.Forms;


namespace ProtocolConversion_WINCE
{
    class Ping1
    {

        public static bool ChectNet()
        {
            bool isSucessed = false;

            byte[] RequestData = Encoding.ASCII.GetBytes(new string('\0', 64));
            //Allocate ICMP_ECHO_REPLY structure

            ICMP_ECHO_REPLY reply = new ICMP_ECHO_REPLY(255);

            reply.DataSize = 255;
            IntPtr pData = LocalAlloc(LMEM_ZEROINIT, reply.DataSize);
            reply.Data = pData;
            IntPtr h = IcmpCreateFile();
            //uint ipaddr = (uint)entry.AddressList[0].Address;//直接写成ip地址
            uint ipaddr = (uint)(IPAddress.Parse("10.34.161.99").Address);
            //listBox1.Items.Clear();

            for (int leng = 0; leng < 2; leng++)
            {
                uint ret = IcmpSendEcho(h, ipaddr, RequestData, (short)RequestData.Length, IntPtr.Zero, reply._Data, reply._Data.Length, 1000);
                int dwErr = 0;
                if (ret == 0)
                {
                    dwErr = GetLastError();
                    if (dwErr != 11010) // If error is other than timeout - display a message
                    //MessageBox.Show("Failed to ping. Error code: " + dwErr.ToString());
                    {
                        isSucessed = false;

                    }
                }
                if (dwErr != 11010)
                //listBox1.Items.Add(string.Format("RTT: {0}, Data Size: {1}; TTL: {2}", reply.RoundTripTime, reply.DataSize, reply.Ttl));
                {
                    //return true;
                    isSucessed = true;
                }
                else
                {
                    isSucessed = false;
                    return false;
                }
                //listBox1.Items.Add("Request timed out");
                //listBox1.SelectedIndex = listBox1.Items.Count - 1;
                Application.DoEvents();
                System.Threading.Thread.Sleep(50);
                //for (int j = 0; j < 8000; j++) ;
                //return isSucessed == true ? true : false;
            }
            IcmpCloseHandle(h);
            LocalFree(reply.Data);

            if (isSucessed)
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        #region Memory Management
        [DllImport("coredll")]
        extern public static IntPtr LocalAlloc(int flags, int size);
        [DllImport("coredll")]
        extern public static IntPtr LocalFree(IntPtr pMem);

        const int LMEM_ZEROINIT = 0x40;

        #endregion


        #region IPHLPAPI P/Invokes
        [DllImport("iphlpapi")]
        extern public static IntPtr IcmpCreateFile();

        [DllImport("iphlpapi")]
        extern public static bool IcmpCloseHandle(IntPtr h);

        [DllImport("iphlpapi")]
        extern public static uint IcmpSendEcho(
                         IntPtr IcmpHandle,
                         uint DestinationAddress,
                         byte[] RequestData,
                         short RequestSize,
                         IntPtr /*IP_OPTION_INFORMATION*/ RequestOptions,
                         byte[] ReplyBuffer,
                         int ReplySize,
                         int Timeout);

        #endregion

        [DllImport("coredll")]
        extern static int GetLastError();

    }
    public class ICMP_ECHO_REPLY
    {
        public ICMP_ECHO_REPLY(int size) { data = new byte[size]; }
        byte[] data;
        public byte[] _Data { get { return data; } }
        public int Address { get { return BitConverter.ToInt32(data, 0); } }
        public int Status { get { return BitConverter.ToInt32(data, 4); } }
        public int RoundTripTime { get { return BitConverter.ToInt32(data, 8); } }
        public short DataSize { get { return BitConverter.ToInt16(data, 0xc); } set { BitConverter.GetBytes(value).CopyTo(data, 0xc); } }
        public IntPtr Data { get { return new IntPtr(BitConverter.ToInt32(data, 0x10)); } set { BitConverter.GetBytes(value.ToInt32()).CopyTo(data, 0x10); } }
        public byte Ttl { get { return data[0x14]; } }
        public byte Tos { get { return data[0x15]; } }
        public byte Flags { get { return data[0x16]; } }
        public byte OptionsSize { get { return data[0x17]; } }
        public IntPtr OptionsData { get { return new IntPtr(BitConverter.ToInt32(data, 0x18)); } set { BitConverter.GetBytes(value.ToInt32()).CopyTo(data, 0x18); } }

    }
}

